#include "qobjectlistview.h"

#include "qformwidget.h"

#include <QItemDelegate>
#include <QPainter>
#include <QApplication>

class QObjectDelegate: public QItemDelegate
{
public :
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

void QObjectDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV3 opt=option;
    QColor c;
    c=QColor(255,191,239);
    if(opt.features & QStyleOptionViewItemV2::Alternate)
    {
        c=c.lighter(112);
    }



    painter->fillRect(option.rect,c);
    opt.state &=~ QStyle::State_HasFocus;
    QItemDelegate::paint(painter,opt,index);
    opt.palette.setCurrentColorGroup(QPalette::Active);
    QColor color=static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor,&opt));
    painter->setPen(color);

    if(index.column()==0)
    {
        int right=option.direction==Qt::LeftToRight?option.rect.right():option.rect.left();
        painter->drawLine(right,option.rect.y(),right,option.rect.bottom());
    }
}

QSize QObjectDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QSize sz=QItemDelegate::sizeHint(option,index);
    sz.setHeight(20);
    return sz;
}

QObjectListView::QObjectListView(QWidget *parent) :
    QTreeWidget(parent),
    m_formWidget(NULL)
{
    this->setFrameStyle(QFrame::NoFrame);

    this->setColumnCount(2);

    this->setHeaderLabels(QStringList()<<"name"<<"type");

    setAlternatingRowColors(true);
    setEditTriggers(QAbstractItemView::EditKeyPressed);

    connect(this,SIGNAL(clicked(QModelIndex)),this,SLOT(clickedItem(QModelIndex)));

    setItemDelegate(new QObjectDelegate);
}

void QObjectListView::setFormWidget(QFormWidget *formWidget)
{
    if(m_formWidget!=NULL)
    {
        disconnect(m_formWidget,SIGNAL(currentChanged(QWidget*)),this,SLOT(selectChanged(QWidget*)));
        disconnect(m_formWidget,SIGNAL(destroyed()),this,SLOT(formDestroyed()));
        disconnect(m_formWidget,SIGNAL(widgetAdd(QWidget*)),this,SLOT(widgetAdd(QWidget*)));
        disconnect(m_formWidget,SIGNAL(widgetRemove(QWidget*)),this,SLOT(widgetRemove(QWidget*)));
        disconnect(m_formWidget,SIGNAL(nameChanged(QWidget*)),this,SLOT(updateObjectName(QWidget*)));
    }
    this->clear();

    m_items.clear();
    m_root=NULL;

    m_formWidget=formWidget;

    if(m_formWidget==NULL)
    {
        return;
    }




    m_root=new QTreeWidgetItem(this);

    m_root->setText(0,m_formWidget->property("pageName").toString());
    m_root->setToolTip(0,m_formWidget->property("pageName").toString());

    QWidgetList list=m_formWidget->widgets();

    QTreeWidgetItem *item;
    QString         str;
    foreach(QWidget* wid,list)
    {
        item=new QTreeWidgetItem(m_root);
        item->setText(0,wid->property("objectName").toString());
        item->setToolTip(0,wid->property("objectName").toString());
        str=wid->property("typeName").toString();
        if(str=="")
        {
            str=wid->metaObject()->className();
        }
        item->setText(1,str);
        item->setToolTip(1,str);
        item->setIcon(1,QIcon(wid->property("typeIcon").toString()));
        m_items.insert(wid,item);
        m_itemToWidget.insert(item,wid);
    }
    this->expandAll();
    connect(m_formWidget,SIGNAL(currentChanged(QWidget*)),this,SLOT(selectChanged(QWidget*)));
    connect(m_formWidget,SIGNAL(destroyed()),this,SLOT(formDestroyed()));
    connect(m_formWidget,SIGNAL(widgetAdd(QWidget*)),this,SLOT(widgetAdd(QWidget*)));
    connect(m_formWidget,SIGNAL(widgetRemove(QWidget*)),this,SLOT(widgetRemove(QWidget*)));
    connect(m_formWidget,SIGNAL(nameChanged(QWidget*)),this,SLOT(updateObjectName(QWidget*)));
    m_root->setSelected(true);
}

void QObjectListView::clickedItem(const QModelIndex &index)
{
    QTreeWidgetItem *item=itemFromIndex(index);

    if(item==m_root)
    {
        m_formWidget->select(m_formWidget);
    }
    else
    {
        m_formWidget->select(m_itemToWidget.value(item));
    }
}

void QObjectListView::selectChanged(QWidget *wid)
{
    this->clearSelection();
    if(wid==m_formWidget)
    {
        m_root->setSelected(true);
    }
    else
    {
        QTreeWidgetItem *item=m_items.value(wid);
        if(item!=NULL)
        {
            item->setSelected(true);
        }
    }
}

void QObjectListView::formDestroyed()
{
    this->clear();

    m_items.clear();
    m_root=NULL;

    m_formWidget=NULL;
}

void QObjectListView::widgetAdd(QWidget *wid)
{
    QTreeWidgetItem *item;
    if(m_items.keys().indexOf(wid)>=0)
    {
        item=m_items.value(wid);
    }
    else
    {
        item=new QTreeWidgetItem(m_root);
    }
    QString         str;

    item->setText(0,wid->property("objectName").toString());
    item->setToolTip(0,wid->property("objectName").toString());
    str=wid->property("typeName").toString();
    if(str=="")
    {
        str=wid->metaObject()->className();
    }
    item->setText(1,str);
    item->setToolTip(1,str);
    item->setIcon(1,QIcon(wid->property("typeIcon").toString()));
    m_items.insert(wid,item);
    m_itemToWidget.insert(item,wid);
}

void QObjectListView::widgetRemove(QWidget *wid)
{
    QTreeWidgetItem *item=m_items.value(wid);
    if(item==NULL)
    {
        return;
    }
    m_root->removeChild(item);
    m_items.remove(wid);
    m_itemToWidget.remove(item);
}

void QObjectListView::updateObjectName(QWidget *wid)
{
    QTreeWidgetItem *item=m_items.value(wid);
    if(item==NULL)
    {
        return;
    }
    item->setText(0,wid->property("objectName").toString());
    item->setToolTip(0,wid->property("objectName").toString());
}
